package graduation.project.body;

import graduation.project.factory.DataAccess;
import graduation.project.store.IResults;

import java.util.ArrayList;

public class Mutants {

	private final String originEx; // Using Expression or String??
	private ArrayList<Expression> mutants;
	private final String mutantsID;
	private final String faultType;
	
	public Mutants(String originEx, String faultType){
		this.originEx = originEx;
		if(faultType == null)
			this.faultType = "Nature";
		else
			this.faultType = faultType;
		mutantsID = Integer.toString(originEx.hashCode()) + "_" + this.faultType + (int)(Math.random() * 1000); // need overlapped the definition of MutantsID;
	}	
	public Mutants(String originEx, String mutantsID, String faultType){
		this.originEx = originEx;
		this.faultType = faultType;
		this.mutantsID = mutantsID;
	}
	
	public String getFaultType(){
		return faultType;
	}
	
	public String getOriginEx(){
		return originEx;
	}
	public String getMutantsID(){
		return mutantsID;
	}
	
	public void setMutants(ArrayList<Expression> mutants){
		this.mutants = mutants;
	}
	public ArrayList<Expression> getMutants(){
		return mutants;
	}
	
	public void addMutant(Expression mutant){
		mutants.add(mutant);
	}
	public void addMutants(Expression[] mutantSet){
		for(int i = 0; i < mutantSet.length; i++){
			mutants.add(mutantSet[i]);
		}
	}
	public void removeMutant(Expression mutant){
		mutants.remove(mutant);
	}

	public Results runTestCases(TestCases tcs){
		if(!(tcs.getOriginEx().equals(originEx)))
			return null;
		Results result = new Results(originEx, mutantsID, tcs.getTestSetID());
		
		ArrayList<TestCase> testSet = tcs.getTestSet();
		Result[] records = new Result[mutants.size()];
		
		String model = tcs.getModel();
		TestCase tempTC;
		Expression tempM;
		boolean isDetected = false;
		int index = 0;
		for(int i = 0; i < mutants.size(); i++){
			tempM = mutants.get(i);
			for(int j = 0; j < testSet.size(); j++){
				tempTC = testSet.get(j);
				if(tempTC.getExpectantResult() != tempM.evaluate(tempTC.getTestData(), model)){
					isDetected = true;
					break;
				}					
			}
			if(isDetected)
				records[index] = new Result(tempM.getExpression(), true);
			else
				records[index] = new Result(tempM.getExpression(), false);
			index++;
		}
	
		result.setRecords(records);
		if(result != null){			
			DataAccess dataA = new DataAccess();
			IResults iRts = dataA.createResults();
			iRts.insertResults(result);
		}
		return result;
	}
	
	public boolean equals(Object obj){
		if(!(obj instanceof Mutants))
			return false;
		if(obj == null)
			return false;
		
		if(this.mutantsID == ((Mutants)obj).getMutantsID())
			return true;
		return false;
	}
	public String toString(){
		return "mutantsID: " + mutantsID + "; Origin Expression: " + originEx;
	}
	
}
